/**
 * 
 */
package de.idgard.android.addon.services.transport;

import android.os.AsyncTask;
import android.util.Log;
import de.idgard.android.addon.services.GlobalServiceRegistry;
import de.idgard.json.transport.CacheHandler;
import de.idgard.json.transport.IDGHttpClient;
import de.idgard.json.transport.JsonServiceTransport;
import de.idgard.json.transport.PayloadParser;
import de.idgard.json.transport.Receiver;
import de.idgard.json.transport.ResponseDescriptor;
import de.idgard.webapp.shared.dto.transport.DataRequest;

/**
 * 
 * @author <a href="mailto:vesko.georgiev@uniscon.com">Vesko Georgiev</a>
 */
public class JsonAndroidTransport extends JsonServiceTransport {

	private IDGHttpClient httpClient;

	public JsonAndroidTransport(String idgardHost) {
		httpClient = new AndroidHttpClient(idgardHost);
	}

	public <Req, Res> void post(String url, DataRequest<Req> requestPayload, Receiver<Res> receiver, PayloadParser<Res> parser, CacheHandler cacheHandler) {
		new JsonRequestTask<Req, Res>(url, requestPayload, receiver, parser, cacheHandler);
	}

	@Override
	public <Req, Res> void post(String url, DataRequest<Req> requestPayload, Receiver<Res> receiver, PayloadParser<Res> parser) {
		new JsonRequestTask<Req, Res>(url, requestPayload, receiver, parser);
	}

	public class JsonRequestTask<Req, Res> extends AsyncTask<Void, Integer, ResponseDescriptor> {

		private DataRequest<Req> requestPayload;
		private Receiver<Res> receiver;
		private PayloadParser<Res> parser;
		private String url;
		private CacheHandler cacheHandler;

		public JsonRequestTask(String url, DataRequest<Req> requestPayload, Receiver<Res> receiver, PayloadParser<Res> parser, CacheHandler cacheHandler) {
			this.url = url;
			this.requestPayload = requestPayload;
			this.receiver = receiver;
			this.parser = parser;
			this.cacheHandler = cacheHandler;

			execute();
		}

		public JsonRequestTask(String url, DataRequest<Req> requestPayload, Receiver<Res> receiver, PayloadParser<Res> parser) {
			this.url = url;
			this.requestPayload = requestPayload;
			this.receiver = receiver;
			this.parser = parser;

			execute();
		}

		@Override
		protected ResponseDescriptor doInBackground(Void... v) {
			return executeRequest(httpClient, requestPayload, url);
		}

		@Override
		protected void onPreExecute() {
			if (requestPayload != null) {
				String id = GlobalServiceRegistry.instance().getBrowserUtilityService().getIDGardData().getIdgardId();
				requestPayload.setSid(id);
			}
			httpClient.onPreExecute();
		}

		@Override
		protected void onPostExecute(ResponseDescriptor res) {
			String jsonPayload = getJsonPayload(requestPayload);
			switch (res.getCode()) {
			case 200:
				Log.i(JsonAndroidTransport.class.getName(), 
						"Request sent successfully to: " + url + "\n" + 
						"With payload: " + jsonPayload + "\n" + 
						"Response is: '" + res.getResponseBody() + "'");
				Res result = parser.parse(res.getResponseBody());
				if (cacheHandler != null) {
					cacheHandler.setResponseObjectAndResolveActualTarget(result);
				}
				receiver.onSuccess(result);
				break;
			case -1:
				Log.e(JsonAndroidTransport.class.getName(),
						"Request failed to: " + url + "\n" + 
						"With payload: " + jsonPayload + "\n" + 
						"Exception is: '" + res.getException() + "'");
				receiver.onException(res.getException());
				break;
			default:
				Log.w(JsonAndroidTransport.class.getName(), 
						"Request failed to: " + url + "\n" + 
						"With payload: " + jsonPayload + "\n" + 
						"Response is: '" + res.getCode() + ": " + res.getResponseBody() + "'");
				receiver.onFailure(res.getCode(), res.getResponseBody());
				break;
			}
		}
	}

	@Override
	protected IDGHttpClient getHttpClient() {
		return httpClient;
	}
}
